package com.dense.kuiniu.shelfcard.card.iccard;

import D1000_Package.D1000_Serial;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * @author Administrator
 * @date 2021/3/2
 * 天腾吐卡机
 */
public class TTCardOutPut implements CardOutPut {
    private byte mMacAddress = 0x00;
    private String mPort;
    private ICardReader mCardReader;
    private ICardBinder mCardBinder;
    private boolean hasOpen = false;


    public TTCardOutPut(String port, ICardReader cardReader, ICardBinder cardBinder) {
        mPort = port;
        mCardReader = cardReader;
        mCardBinder = cardBinder;
    }


    @Override
    public void getCard(ResultListener listener) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Throwable {
                CodeResult result;
                if (!hasOpen) {
                    result = open(mPort);
                    if (result.getCode() == 0) {
                        hasOpen = true;
                        Thread.sleep(1000);
                    }
                }
                result = sendToRead();
                if (result.getCode() == 0) {
                    Thread.sleep(1000);
                    String carNo = mCardReader.readCard();
                    if (!carNo.isEmpty()) {
                        if (mCardBinder.bindCard(carNo)) {
                            result = sendToExport();
                            if (result.getCode() == 0) {
                                emitter.onNext(carNo);
                            }
                        } else {
                            emitter.onError(new Throwable("绑定失败"));
                        }
                    } else {
                        //todo 读卡失败
                    }
                } else {
                    emitter.onError(new Throwable(result.getMsg()));
                }
            }
        }).observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onNext(@NonNull String cardNo) {
                        if (listener != null) {
                            listener.result(cardNo);
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        if (listener != null) {
                            listener.error(e.getMessage());
                        }
                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    private CodeResult open(String port) {
        CodeResult result = new CodeResult();
        int re = D1000_Serial.D1000_CommOpen(port);
        if (re == 0) {
            byte i;
            for (i = 0; i < 16; i++) {
                re = D1000_Serial.D1000_AutoTestMac((byte) i);
                if (re == 0) {
                    mMacAddress = i;
                    break;
                }
            }
            if (i == 16 && mMacAddress == 0) {
                result.setCode(re);
                result.setMsg(D1000_Serial.ErrorCode(re, 0));
            } else {
                result.setCode(0);
                result.setMsg("成功");
            }

        } else {
            result.setCode(re);
            result.setMsg(D1000_Serial.ErrorCode(re, 0));
        }
        return result;
    }

    /**
     * 将卡发送到读卡处
     * @return 结果
     */
    private CodeResult sendToRead() {
        byte[] SendCmd = new byte[3];
        SendCmd[0] = 0x46;
        SendCmd[1] = 0x43;
        SendCmd[2] = 0x37;
        int re = D1000_Serial.D1000_SendCmd(mMacAddress, SendCmd, 3);
        return new CodeResult(re, D1000_Serial.ErrorCode(re, 0));
    }

    private CodeResult querySensor() {
        byte[] states = new byte[4];
        int re = D1000_Serial.D1000_SensorQuery(mMacAddress, states);
        return new CodeResult(re, StateInfo(states));
    }
    /**
     * 将卡发送到取卡处
     * @return 结果
     */
    private CodeResult sendToExport() {
        byte[] SendCmd = new byte[3];
        SendCmd[0] = 0x46;
        SendCmd[1] = 0x43;
        SendCmd[2] = 0x34;
        int re = D1000_Serial.D1000_SendCmd(mMacAddress, SendCmd, 3);
        return new CodeResult(re, D1000_Serial.ErrorCode(re, 0));
    }

    private String StateInfo(byte[] stateInfo) {
        String msg = "";
        switch (stateInfo[0]) {
            case 0x38://保留
                break;
            case 0x34://命令不能执行
                msg = ShowMessage("命令不能执行，请点击“复位”");
                break;
            case 0x32://准备卡失败
                msg = ShowMessage("准备卡失败，请点击“复位”");
                break;
            case 0x31://正在准备卡
                msg = ShowMessage("正在准备卡");
                break;
            case 0x30://机器空闲
                msg = ShowMessage("机器空闲");
                break;
        }

        switch (stateInfo[1]) {
            case 0x38://正在发卡
                msg = ShowMessage("正在发卡");
                break;

            case 0x34://正在收卡
                msg = ShowMessage("正在收卡");
                break;

            case 0x32://发卡出错
                msg = ShowMessage("发卡过程出错,请点击复位");
                break;

            case 0x31://收卡出错
                msg = ShowMessage("收卡过程出错,请点击复位");
                break;

            case 0x30://没有任何动作
                msg = ShowMessage("没有任何动作");
                break;
        }
        switch (stateInfo[2]) {
            case 0x39:
                msg = ShowMessage("回收卡箱已满");

                msg = ShowMessage("卡箱预空");

                break;
            case 0x38://无捕卡

                msg = ShowMessage("回收卡箱已满");

                msg = ShowMessage("卡箱非预空");
                break;

            case 0x34://重叠卡
                msg = ShowMessage("重叠卡");
                break;

            case 0x32://卡堵塞
                msg = ShowMessage("卡堵塞");
                break;

            case 0x31://卡箱预空
                msg = ShowMessage("卡箱预空");
                break;

            case 0x30://卡箱为非预空状态
                msg = ShowMessage("卡箱为非预空状态");
                break;

        }

        switch (stateInfo[3]) {
            case 0x3E://只有一张卡，在传感器２-３位置
                msg = ShowMessage("只有一张卡，在传感器２-３位置");
                break;

            case 0x3B://只有一张卡，在传感器１-２位置
                msg = ShowMessage("只有一张卡，在传感器１-２位置");
                break;

            case 0x39://只有一张卡，在传感器１位置
                msg = ShowMessage("只有一张卡，在传感器１位置");
                break;

            case 0x38://卡箱是空的已经无任何卡片
                msg = ShowMessage("卡箱是空的已经无任何卡片");
                break;

            case 0x36://在传感器２和３的位置
                msg = ShowMessage("卡在传感器２和３的位置");
                break;

            case 0x34://在传感器３位置，预发卡位置
                msg = ShowMessage("卡在传感器３位置，预发卡位置");
                break;

            case 0x33://在传感器１和２的位置(读卡位置)
                msg = ShowMessage("卡在传感器１和２的位置(读卡位置)");
                break;

            case 0x32://在传感器２的位置
                msg = ShowMessage("在传感器２的位置");
                break;

            case 0x31://在卡口位置传感器１位置(取卡位置)
                msg = ShowMessage("卡在卡口位置传感器１位置(取卡位置)");
                break;
        }
        return msg;
    }

    private String ShowMessage(String msg) {
        return msg;
    }
}